#include <iostream>
#include <pthread.h>
#include <vector>
#include <unistd.h>
#include <string>
#include <cstdio>
#include "mutex.hpp"
#define NUM 4
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
int tickets = 1000;
class threadData
{
public:
    threadData(int number /*, pthread_mutex_t* lock*/)
    {
        _threadname += "thread-" + std::to_string(number);
        //_lock = lock;
    }

public:
    std::string _threadname;
    pthread_mutex_t *_lock;
};
// void* getticket(void* args)
// {
//     threadData* td = static_cast<threadData*>(args);
//     const char* name = td->_threadname.c_str();
//     while(true)
//     {
//         //pthread_mutex_lock(td->_lock);
//         pthread_mutex_lock(&lock);
//         if(tickets > 0)
//         {
//             usleep(1000);
//             printf("who=%s, get a ticket: %d\n", name, tickets);
//             tickets--;
//             //pthread_mutex_unlock(td->_lock);
//             pthread_mutex_unlock(&lock);
//         }
//         else{
//             //pthread_mutex_unlock(td->_lock);
//             pthread_mutex_unlock(&lock);
//             break;
//         }
//         usleep(13);
//     }
//     printf("%s quit\n", name);
//     return nullptr;
// }
void *getticket(void *args)
{
    threadData *td = static_cast<threadData *>(args);
    const char *name = td->_threadname.c_str();
    while (true)
    {
        {
            LockGuard lockguard(&lock);//RAII风格的锁
            if (tickets > 0)
            {
                usleep(1000);
                printf("who=%s, get a ticket: %d\n", name, tickets);
                tickets--;
            }
            else
                break;
        }
        usleep(13);
    }
    printf("%s quit\n", name);
    return nullptr;
}
int main()
{
    // pthread_mutex_t lock;
    // pthread_mutex_init(&lock, nullptr);
    std::vector<pthread_t> tids;
    std::vector<threadData *> threaddatas;
    for (int i = 0; i < NUM; i++)
    {
        pthread_t tid;
        threadData *td = new threadData(i /*, &lock*/);
        threaddatas.push_back(td);
        pthread_create(&tid, nullptr, getticket, threaddatas[i]);
        tids.push_back(tid);
    }
    for (auto e : tids)
    {
        pthread_join(e, nullptr);
    }
    for (auto e : threaddatas)
    {
        delete e;
    }
    // pthread_mutex_destroy(&lock);
    return 0;
}